package me.sealer.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;

public class IpUtil {

    /*public static void main(String[] args) {
        // 如果不设置，只要代理IP和代理端口正确,此项不设置也可以
        System.getProperties().setProperty("http.proxyHost", "10.22.40.32");
        System.getProperties().setProperty("http.proxyPort", "8080");
        // 判断代理是否设置成功
        // 发送 GET 请求
        System.out.println(sendGet("http://www.baidu.com","wd=网盘搜索"));
        // 发送 POST 请求
    }*/

    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url   发送请求的URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static String escape(String src) {
        int i;
        char j;
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length() * 6);
        for (i = 0; i < src.length(); i++) {
            j = src.charAt(i);
            if (Character.isDigit(j) || Character.isLowerCase(j)
                    || Character.isUpperCase(j))
                tmp.append(j);
            else if (j < 256) {
                tmp.append("%");
                if (j < 16)
                    tmp.append("0");
                tmp.append(Integer.toString(j, 16));
            } else {
                tmp.append("%u");
                tmp.append(Integer.toString(j, 16));
            }
        }
        return tmp.toString();
    }

    /**
     * 唯一对外开放的静态工具方法, 可以获取到本机的外网地址
     * 获取本机外网ip的默认方法, 从ip138获取
     *
     * @return
     */
    public static String defaultRetrieveLocalIp() {
        String ipRemoteQuery = "http://www.ip138.com/ip2city.asp";
        String ip = getWebIP(ipRemoteQuery);
        return ip;
    }

    /**
     * 获取外网地址
     * 该方法定义为私有方法, 目的是简化调用, 否则还要自己输入访问地址http://www.ip138.com/ip2city.asp
     *
     * @param strUrl 从哪个服务借口获取到本机外网IP地址 一般从 ip138.com
     * @return
     */
    private static String getWebIP(String strUrl) {
        try {

            String webContent = retrieveWebPage(strUrl);
            int start = webContent.indexOf("[") + 1;
            int end = webContent.indexOf("]");
            //获取网页中  当前 的 外网IP
            webContent = webContent.substring(start, end);
            return webContent;

        } catch (Exception e) {
            e.printStackTrace();//打印访问ip获取网址错误堆栈
            return "127.0.0.1";//出错后默认返回本机内网ip
        }
    }

    /**
     * 根据网址获取网页内容
     * @param strUrl
     * @return
     * @throws Exception
     */
    public static String retrieveWebPage(String strUrl) throws Exception {
        //连接网页
        URL url = new URL(strUrl);
        BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
        String s = "";
        StringBuffer sb = new StringBuffer("");
        String webContent = "";
        //读取网页信息
        while ((s = br.readLine()) != null) {
            sb.append(s + "\r\n");
        }
        br.close();
        //网页信息
        webContent = sb.toString();
        return webContent;
    }

}